#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#define NUM 10
typedef void (*func) (); //函数指针
func HandleTask[NUM]; //函数指针数组
//任务样例
void task1()
{
    printf("running task1\n");
}


void task2()
{
    printf("running task2\n");
}

void task3()
{
    printf("running task3\n");
}


void LoadTask()
{
    memset(HandleTask,0,sizeof(HandleTask));
    HandleTask[0] = task1;
    HandleTask[1] = task2;
    HandleTask[2] = task3;
}

int main()
{
    pid_t id = fork();
    assert(id != -1);
    if(id == 0)
    {
        //child
       int cnt = 5;
       while(cnt--)
       {
           printf("child : %d,parent: %d, ---%d\n",getpid(),getppid(),cnt);
           sleep(2);
       }
        exit(10);
    }

    //parent
    LoadTask();  //加载任务
    int status = 0;
    while(1)
    {
        pid_t ret = waitpid(id,&status,WNOHANG);//WNOHANG:非阻塞等待
        if(ret == 0)
        {
            //表示waitpid调用成功，但子进程没有退出，
            //非阻塞等待的优点：可以在等待过程中执行别的任务
            printf("child running...,parent do other things\n");
            for(int i = 0; HandleTask[i]!=NULL;i++)
            {
                HandleTask[i]();
            }
        }
        else if(ret == id && ret >0)
        {
            //表示waitpid调用成功，子进程退出
            printf("child exit success，exit_code：%d,sig_code: %d\n",(status>>8) & 0xFF,status & 0x7F);
            break;
        }
        else
        {
            //调用失败
            printf("waitpid failed\n");
            break;
        }
        sleep(1);
    }







    ////parent
    //int status = 0;
    //int ret = waitpid(id,&status,0);
    ////为1表示正常退出 等价于 signal = 0
    ////为0表示程序异常
    ////阻塞式等待--父进程会一直等待子进程直到子进程退出
    //if(WIFEXITED(status)) //0 or 1
    //{
    //    //获取子进程的退出码
    //    printf("childe exit success , exid code:%d\n",WEXITSTATUS(status));
    //}
    //else
    //{
    //    printf("child exit failed,sig:%d\n",(status) & 0x7F);
    //}
    
    return 0;
}
